package com.example.userserver.sms.smssend;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.commons.entity.MessagefailsDO;
import com.example.commons.entity.MessagelogsDO;
import com.example.commons.utils.ApiEnumError;
import com.example.commons.utils.EhCacheUtil;
import com.example.commons.utils.JinZhiException;
import com.example.userserver.config.RedisUtil;
import com.example.userserver.service.DicUserService;
import com.example.userserver.service.UserService;
import com.example.userserver.sms.config.AlyUserProperties;
import com.example.userserver.sms.config.MapToJsonStr;
import com.example.userserver.sms.server.MessagefailsService;
import com.example.userserver.sms.server.MessagelogsService;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Slf4j
@Service
public class SmsSendUserServerImpl implements SmsSendServer{
    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private MessagefailsService messagefailsService;
    @Autowired
    private AlyUserProperties properties;
    @Autowired
    private MessagelogsService messagelogsService;
    @Autowired
    private DicUserService dictService;
    @Autowired
    private UserService userService;
    @Override
    public void verify(String prefix, String phone, String code) {

    }

    @Override
    public boolean loginVerify(String prefix, String phone, String code) {
        return false;
    }

    @Override
    public boolean verify1(String prefix, String phone, String code) {
        return false;
    }
    /**
     * <pre>
     * 生成随机码
     * </pre>
     */
    public String getCode(){
        return new Random().nextInt(8999) + 1000 + "";
    }

    /**
     * String cacheName, String key, Object value, Integer timeToLiveSeconds
     * @param mobile
     * @param templateCode
     * @return
     */
    @Override
    public boolean send(String mobile, String templateCode) {

        String codes=getCode();
        log.info("发送验证码为："+codes);
        try {

            EhCacheUtil.put(mobile+"code",codes);
        } catch (Exception e) {
            e.printStackTrace();
        }
     boolean b=   redisUtil.set(mobile+RedisUtil.code,codes,300);
        redisUtil.set(mobile,codes,10);

        Map templateParam = new HashMap();
        templateParam.put("code",codes);
        SendSmsResponse response1 =new SendSmsResponse();
        try {
             response1 = this.sendSms(mobile,templateCode,templateParam);
        } catch (ClientException e) {
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return response1.getCode()!=null&&response1.getCode().equals("OK") ?true:false;
    }


    public SendSmsResponse sendSms(String mobile, String templateCode, Map templateParam) throws ClientException, JsonProcessingException {
        QueryWrapper<MessagelogsDO> wrapperSend=new QueryWrapper();
        wrapperSend.eq("phone",mobile);
        wrapperSend.like("createDate", LocalDate.now());
        Integer countSend=    messagelogsService.count(wrapperSend);

        Map<String,String> map = new HashMap<>();
        map.put("name","短信重发次数");
        map.put("type","smsFailsNum");
        String   sms_fails_num=  dictService.selDicBy(map);
        if(Integer.valueOf(sms_fails_num)<=countSend){
            throw new JinZhiException(ApiEnumError.apiSmsSendFailedS.getCode(),ApiEnumError.apiSmsSendFailedS.getMsg());
        }

        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");

        //初始化acsClient,暂不支持region化
        IClientProfile profile = DefaultProfile.getProfile(properties.getProfile(), properties.getAccessKeyId(), properties.getAccessKeySecret());
        DefaultProfile.addEndpoint(properties.getProfile(), properties.getProfile(), properties.getProduct(), properties.getDomain());
        IAcsClient acsClient = new DefaultAcsClient(profile);

        //组装请求对象-具体描述见控制台-文档部分内容
        SendSmsRequest request = new SendSmsRequest();
        //必填:待发送手机号
        request.setPhoneNumbers(mobile);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName(properties.getSignName());
        //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode(templateCode);
        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
        request.setTemplateParam(MapToJsonStr.conversion(templateParam));

        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
        //request.setSmsUpExtendCode("90997");

        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
        //request.setOutId("yourOutId");
        //hint 此处可能会抛出异常，注意catch
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
        //插入日志
        MessagelogsDO messagelogsDO = new MessagelogsDO();
        messagelogsDO.setPhone(mobile);
        messagelogsDO.setState(sendSmsResponse.getCode());
        messagelogsDO.setSmsDemo(templateCode);
        messagelogsDO.setParameters(templateParam.toString());
        messagelogsDO.setPlatfromMsg(properties.getSignName());
        messagelogsService.save(messagelogsDO);

        if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
            //redisUtil.set(mobile+RedisUtil.code,mobile,300);
            log.info("【SMS】阿里云发送短信成功，code:{},message:{},requestId:{},bizId:{}", sendSmsResponse.getCode(), sendSmsResponse.getMessage(), sendSmsResponse.getRequestId(), sendSmsResponse.getBizId());
        }else {
            //插入失败日志，定时任务记录重发
            MessagefailsDO messagefailsDO = new MessagefailsDO();
            messagefailsDO.setErrorCode(sendSmsResponse.getCode());
            messagefailsDO.setErrorMsg(sendSmsResponse.getMessage());

            messagefailsDO.setAgains(Integer.parseInt(sms_fails_num));
            messagefailsDO.setAgains(0);//暂定默认为0
            messagefailsDO.setState(2);
            messagefailsService.save(messagefailsDO);
            log.warn("【SMS】阿里云发送失败，code:{},message:{},requestId:{},bizId:{},mobile:{},signName:{},templateCode:{},templateParam:{}", sendSmsResponse.getCode(), sendSmsResponse.getMessage(), sendSmsResponse.getRequestId(), sendSmsResponse.getBizId(), mobile, properties.getSignName(), templateCode, templateParam);
            // throw new IFastApiException(EnumErrorCode.apiSmsSendFailed.getCodeStr());
            throw new JinZhiException(ApiEnumError.apiSmsSendFailedSQ.getCode(),ApiEnumError.apiSmsSendFailedSQ.getMsg());

        }
        return sendSmsResponse;
    }

}
